﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;

namespace SimplexEngine
{
    internal class HardwareMeshBufferManager
    {
        /// <summary>
        /// get hardware mesh buffer
        /// </summary>
        /// <param name="mesh_buffer">mesh buffer to get hardware mesh buffer</param>
        /// <returns>hardware mesh buffer for success</returns>
        public HardwareMeshBuffer GetHardwareMeshBuffer(IMeshBuffer mesh_buffer)
        {            
            HardwareMeshBuffer buffer = null;
            lock (hardware_mesh_buffers)
            {
                if (hardware_mesh_buffers.TryGetValue(mesh_buffer, out buffer))
                    return buffer;
            }
            return null;
        }

        /// <summary>
        /// create a hardware mesh buffer
        /// </summary>
        /// <param name="mesh_buffer">mesh buffer to create hardware mesh buffer</param>
        /// <returns>hardware mesh buffer for success</returns>
        public HardwareMeshBuffer CreateHardwareMeshBuffer(IMeshBuffer mesh_buffer)
        {            
            // have created?
            if (GetHardwareMeshBuffer(mesh_buffer) != null)
                return null;

            HardwareMeshBuffer buffer = new HardwareMeshBuffer();
            GraphicsDevice device = Root.Instance.RenderSystem.GraphicsDevice;
            buffer.VertexBuffer = new VertexBuffer(device, typeof(Vertex), (int)mesh_buffer.GetVertexCount(), BufferUsage.WriteOnly);
            buffer.VertexBuffer.SetData<Vertex>(mesh_buffer.GetVertices());

            buffer.IndefBuffer = new IndexBuffer(device, typeof(int), (int)mesh_buffer.GetIndexCount(), BufferUsage.WriteOnly);
            buffer.IndefBuffer.SetData<int>(mesh_buffer.GetIndices());

            lock (hardware_mesh_buffers)
            {
                hardware_mesh_buffers.Add(mesh_buffer, buffer);
            }

            return buffer;
        }

        /// <summary>
        /// remove hardware mesh buffer
        /// </summary>
        /// <param name="mesh_buffer">mesh buffer to remove hardware mesh buffer</param>
        public void RemoveHardwareMeshBuffer(IMeshBuffer mesh_buffer)
        {
            lock (hardware_mesh_buffers)
            {
                if (hardware_mesh_buffers.ContainsKey(mesh_buffer))
                    hardware_mesh_buffers.Remove(mesh_buffer);
            }
        }

        // hardware buffers
        private Dictionary<IMeshBuffer, HardwareMeshBuffer> hardware_mesh_buffers = new Dictionary<IMeshBuffer, HardwareMeshBuffer>();
    }
}
